package io.kiki.stack.netty.util;

import io.netty.channel.Channel;

import java.net.InetSocketAddress;
import java.net.SocketAddress;

public class InetSocketAddressUtil {
    /**
     * Parse the socket address, omit the leading "/" if present.
     * <p>
     * e.g.1 /127.0.0.1:1234 -> 127.0.0.1:1234
     * e.g.2 sofatest-2.stack.alipay.net/10.209.155.54:12200 -> 10.209.155.54:12200
     */
    public static String parseSocketAddressToString(SocketAddress socketAddress) {
        if (socketAddress != null) {
            return doParse(socketAddress.toString().trim());
        }
        return StringUtils.EMPTY;
    }

    /**
     * <ol>
     * <li>if an address starts with a '/', skip it.
     * <li>if an address contains a '/', substring it.
     * </ol>
     */
    private static String doParse(String addr) {
        if (StringUtils.isBlank(addr)) {
            return StringUtils.EMPTY;
        }
        if (addr.charAt(0) == '/') {
            return addr.substring(1);
        } else {
            int len = addr.length();
            for (int i = 1; i < len; ++i) {
                if (addr.charAt(i) == '/') {
                    return addr.substring(i + 1);
                }
            }
            return addr;
        }
    }

    public static String parseLocalAddress(final Channel channel) {
        if (null == channel) {
            return StringUtils.EMPTY;
        }
        final InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.localAddress();
        return doParse(inetSocketAddress != null ? inetSocketAddress.toString().trim() : StringUtils.EMPTY);
    }


    public static String parseLocalHostName(final Channel channel) {
        if (null == channel) {
            return StringUtils.EMPTY;
        }
        final InetSocketAddress InetSocketAddress = (InetSocketAddress) channel.remoteAddress();
        if (InetSocketAddress != null) {
            return InetSocketAddress.getAddress().getHostName();
        }
        return StringUtils.EMPTY;
    }

    public static String parseLocalIp(final Channel channel) {
        if (null == channel) {
            return StringUtils.EMPTY;
        }
        final InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.localAddress();
        if (inetSocketAddress != null) {
            return inetSocketAddress.getAddress().getHostAddress();
        }
        return StringUtils.EMPTY;
    }

    public static int parseLocalPort(final Channel channel) {
        if (null == channel) {
            return -1;
        }
        final InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.localAddress();
        if (inetSocketAddress != null) {
            return inetSocketAddress.getPort();
        }
        return -1;
    }


    public static String parseRemoteAddress(final Channel channel) {
        if (null == channel) {
            return StringUtils.EMPTY;
        }
        final InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.remoteAddress();
        return doParse(inetSocketAddress != null ? inetSocketAddress.toString().trim() : StringUtils.EMPTY);
    }


    public static String parseRemoteHostName(final Channel channel) {
        if (null == channel) {
            return StringUtils.EMPTY;
        }
        final InetSocketAddress InetSocketAddress = (InetSocketAddress) channel.remoteAddress();
        if (InetSocketAddress != null) {
            return InetSocketAddress.getAddress().getHostName();
        }
        return StringUtils.EMPTY;
    }

    public static String parseRemoteIp(final Channel channel) {
        if (null == channel) {
            return StringUtils.EMPTY;
        }
        final InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.remoteAddress();
        if (inetSocketAddress != null) {
            return inetSocketAddress.getAddress().getHostAddress();
        }
        return StringUtils.EMPTY;
    }

    public static int parseRemotePort(final Channel channel) {
        if (null == channel) {
            return -1;
        }
        final InetSocketAddress inetSocketAddress = (InetSocketAddress) channel.remoteAddress();
        if (inetSocketAddress != null) {
            return inetSocketAddress.getPort();
        }
        return -1;
    }


}
